Skip to content

feat(pitot): add Devin ACP adapter (10th supported adapter) - #259

Merged
bigboateng merged 5 commits into
mainfrom
codex/devin-pitot-adapter
Jul 31, 2026
Merged

feat(pitot): add Devin ACP adapter (10th supported adapter)#259
bigboateng merged 5 commits into
mainfrom
codex/devin-pitot-adapter

Conversation

@bigboateng

Copy link
Copy Markdown
Contributor

Summary

Adds Devin CLI (pinned 3000.3.22) as Pitot's tenth supported adapter, integrated through its stateful ACP boundary rather than lifecycle hooks. Pitot's public event envelope stays at protocol v1; the existing shell Controller contract is unchanged.

Devin's PreToolUse/PermissionRequest hooks were ruled out empirically: in headless --print mode a denial terminates the turn instead of returning the denied tool result to the model, which breaks Pitot's supervised causal loop. Devin's devin acp mode passes that requirement: session/request_permission + reject_once marks the tool call failed, feeds the rejection back to the model, and the turn continues. Full investigation and binary-observed receipts are in labs/15-pitot/pitot/docs/devin-adapter-research.md and docs/evidence/devin-acp-3000.3.22.json.

Changes

  • ACP client (pitot/internal/devinacp/client.go): dependency-free stdio JSON-RPC ACP v1 client — initialize, one session, one prompt; correlates session/update rawInput.command by session + toolCallId; delivers the existing action.requested shell event; maps allow → allow_once, deny/fault → reject_once; never selects persistent/bypass permissions; fails closed (reject_once) on unknown commands, missing correlation, non-shell permissions, malformed messages, or missing options.
  • CLI surfaces: pitot acp devin --runtime PATH --prompt TEXT ... for manually managed runtimes; pitot dev --host devin -- devin -p "PROMPT" transparently launches devin acp. pitot init --host devin prints ACP usage (no hook files); doctor --host devin verifies binary, version, and devin acp --help; pitot hook devin rejects with ACP guidance. Single-prompt only for the initial release; unsupported flags return precise usage errors.
  • Transport-neutral capability: hook_control renamed action_control; CapabilityHookControl retained as a deprecated Go alias. Verification manifest bumped to schema v7 with Devin as integration: acp_client.
  • Installer: devin_release installer using the version-specific official manifest with platform/arch selection and archive SHA-256 verification.
  • Windows fix (de6e255a): explicit APPDATA/LOCALAPPDATA isolation roots so Devin resolves its config directory in isolated runtimes.
  • Docs, release notes (2026-07-31-devin-acp-support.md), generated README inventory, and distribution projection updated.

Verification

  • Fake-ACP Go tests: initialization, session, prompt completion, output relay, allow, deny-and-continue, correlation, non-shell rejection, malformed JSON-RPC, missing options, cancellation, child failure.
  • Deterministic Devin Connect/protobuf model proxy proving the denied result reaches the next model request; real-agent driver extended with an ACP receipt path (two unique actions, Controller outcomes [allow, deny], exactly one canary execution, denied-canary absence, model continuation, nonce-bound final output, zero exit).
  • Local: go test ./..., full Python/supervisor suites, wind-tunnel, projection checks — green.
  • Real pinned binaries: macOS and Linux x86_64 E2E passed locally; unified CI matrix run 30618922361 passed all 30 agent/platform cells (including native Windows Devin) plus the three runtime-capability cells — 34/34 green.

Disclosure-Reviewed: reviewed — public-safe only, private facet kept out of this commit
Disclosure-Reviewed: reviewed — public-safe only, private facet kept out of this commit
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown

Pitot coding-agent E2E

Intelligence Flow is the verification source; Pitot's public README carries the latest main status.

Agent Ubuntu macOS Windows Result Evidence
Claude ✅ Pass · real CLI 2.1.217 · native · binary-observed anthropic messages ✅ Pass · real CLI 2.1.217 · native · binary-observed anthropic messages ✅ Pass · real CLI 2.1.217 · native · binary-observed anthropic messages ✅ Passing All platforms are required
Cursor ✅ Pass · real CLI 2026.07.20-8cc9c0b · native · binary-observed cursor connect proto ✅ Pass · real CLI 2026.07.20-8cc9c0b · native · binary-observed cursor connect proto ✅ Pass · real CLI 2026.07.20-8cc9c0b · WSL · binary-observed cursor connect proto ✅ Passing All platforms are required
Codex ✅ Pass · real CLI 0.145.0 · native · binary-observed openai responses ✅ Pass · real CLI 0.145.0 · native · binary-observed openai responses ✅ Pass · real CLI 0.145.0 · native · binary-observed openai responses ✅ Passing All platforms are required
Devin ✅ Pass · real CLI 3000.3.22 · native · binary-observed devin connect proto ✅ Pass · real CLI 3000.3.22 · native · binary-observed devin connect proto ✅ Pass · real CLI 3000.3.22 · native · binary-observed devin connect proto ✅ Passing All platforms are required
GitHub Copilot CLI ✅ Pass · real CLI 1.0.73 · native · binary-observed openai chat ✅ Pass · real CLI 1.0.73 · native · binary-observed openai chat ✅ Pass · real CLI 1.0.73 · native · binary-observed openai chat ✅ Passing All platforms are required
Gemini ✅ Pass · real CLI 0.51.0 · native · binary-observed gemini generate content ✅ Pass · real CLI 0.51.0 · native · binary-observed gemini generate content ✅ Pass · real CLI 0.51.0 · native · binary-observed gemini generate content ✅ Passing All platforms are required
Kimi Code ✅ Pass · real CLI 0.29.0 · native · binary-observed openai chat ✅ Pass · real CLI 0.29.0 · native · binary-observed openai chat ✅ Pass · real CLI 0.29.0 · native · binary-observed openai chat ✅ Passing All platforms are required
OpenCode ✅ Pass · real CLI 1.18.4 · native · binary-observed openai responses ✅ Pass · real CLI 1.18.4 · native · binary-observed openai responses ✅ Pass · real CLI 1.18.4 · native · binary-observed openai responses ✅ Passing All platforms are required
Pi ✅ Pass · real CLI 0.81.1 · native · binary-observed openai chat ✅ Pass · real CLI 0.81.1 · native · binary-observed openai chat ✅ Pass · real CLI 0.81.1 · native · binary-observed openai chat ✅ Passing All platforms are required
Qwen Code ✅ Pass · real CLI 0.20.1 · native · binary-observed openai chat ✅ Pass · real CLI 0.20.1 · native · binary-observed openai chat ✅ Pass · real CLI 0.20.1 · native · binary-observed openai chat ✅ Passing All platforms are required

Runtime capabilities

Capability Ubuntu macOS Windows Result
pitot request ✅ Pass · real runtime allow/deny ✅ Pass · real runtime allow/deny ✅ Pass · real runtime allow/deny ✅ Passing

Source commit: 61a75e2cbbfe

Devin's HTTP client pools connections; the deterministic Connect proxy
spoke HTTP/1.0 and closed the socket after every response. A request
written to the stale pooled connection can black-hole until the CLI's
10s team-settings deadline expires, killing session/new before the
negative-phase check can observe anything (seen intermittently on the
Windows cell; the same run's log shows the fast-fail variant of the
race recovered by Devin's 250ms retry at init).

Keep-alive removes the stale-close race: protocol_version HTTP/1.1 and
an exact content-length on every response path, including the GET 404.

Disclosure-Reviewed: reviewed — public-safe only, private facet kept out of this commit
…odies

Round 2 on the intermittent Windows Devin cell. New evidence from run
30629363835 refutes the stale-connection reading: the same 10s
team-settings timeout occurred with keep-alive active, attempt 1 fails
instantly on a fresh process during Devin's startup burst, the hang is
a single request with no transient retries, and other requests were
served concurrently (auxiliary_requests=10).

The mechanism consistent with all observations is listen-backlog
overflow: socketserver defaults request_queue_size to 5, Devin bursts
more concurrent connections than that at startup/session creation, and
Windows either RSTs the overflowed SYN (the fast ConnectionFailed) or
silently drops it so the client retransmit schedule outlives the 10s
deadline (the single hang). Linux/macOS backlog semantics differ,
matching the Windows-only intermittency.

- request_queue_size=128 (+ daemon_threads) on the serving socket
- drain request bodies exactly (content-length and chunked) so a
  kept-alive connection can never desync on an unconsumed body

Disclosure-Reviewed: reviewed — public-safe only, private facet kept out of this commit
Round-2 evidence eliminated the startup-burst fast-fail (backlog fix
held: team settings ready in 8ms) but the session/new refresh still
black-holes for exactly 10s as a single request, under both HTTP/1.0
and HTTP/1.1 proxies. The remaining question is binary and only CI can
answer it: does that request reach the proxy at all, and on which
connection.

The proxy now journals CONN open/close and REQ/RES lines (client port,
path, framing, duration) to a file, and the driver prints the journal
after each Devin phase. Receipt schema unchanged.

Disclosure-Reviewed: reviewed — public-safe only, private facet kept out of this commit
@bigboateng
bigboateng merged commit 57a17ed into main Jul 31, 2026
45 checks passed
@bigboateng
bigboateng deleted the codex/devin-pitot-adapter branch July 31, 2026 12:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant